package async

import (
	"sen-golang-study/go_game_study/hero_story_go_server/common/main_thread"
	"sync/atomic"
)

// AsyncResult 异步业务结果
type AsyncResult struct {
	returnedObj  interface{}
	completeFunc func()

	hasReturnedObj                   int32
	hasCompleteFunc                  int32
	completeFuncHasAlreadyBeenCalled int32
}

// NewAsyncResult 创建异步结果
func NewAsyncResult() *AsyncResult {
	return &AsyncResult{}
}

// GetReturnedObj 获取返回对象
func (result *AsyncResult) GetReturnedObj() interface{} {
	return result.returnedObj
}

// SetReturnObj 设置返回对象
func (result *AsyncResult) SetReturnObj(val interface{}) {
	if atomic.CompareAndSwapInt32(&result.hasReturnedObj, 0, 1) {
		result.returnedObj = val
		result.DoComplete()
	}
}

// OnComplete 设置完成回调
func (result *AsyncResult) OnComplete(completeFunc func()) {
	if atomic.CompareAndSwapInt32(&result.hasCompleteFunc, 0, 1) {
		result.completeFunc = completeFunc

		if result.hasReturnedObj == 1 {
			result.DoComplete()
		}
	}
}

// SetReturnValue 设置返回值
func (result *AsyncResult) SetReturnValue(val interface{}) {
	result.SetReturnObj(val)
}

// SetError 设置错误
func (result *AsyncResult) SetError(err error) {
	result.SetReturnObj(err)
}

// HasError 检查是否有错误
func (result *AsyncResult) HasError() bool {
	if result.returnedObj == nil {
		return false
	}
	_, isError := result.returnedObj.(error)
	return isError
}

// GetError 获取错误
func (result *AsyncResult) GetError() error {
	if result.returnedObj == nil {
		return nil
	}
	if err, ok := result.returnedObj.(error); ok {
		return err
	}
	return nil
}

// GetReturnValue 获取返回值（非错误情况下）
func (result *AsyncResult) GetReturnValue() interface{} {
	if result.HasError() {
		return nil
	}
	return result.returnedObj
}

// DoComplete 执行完成回调
func (result *AsyncResult) DoComplete() {
	if result.completeFunc != nil &&
		atomic.CompareAndSwapInt32(&result.completeFuncHasAlreadyBeenCalled, 0, 1) {
		main_thread.PushTask(result.completeFunc)
	}
}